package com.imooc.miaoshaproject.service.impl;

import com.imooc.miaoshaproject.mapper.UserDOMapper;
import com.imooc.miaoshaproject.exceptions.ServiceException;
import com.imooc.miaoshaproject.exceptions.ErrorCodeEnum;
import com.imooc.miaoshaproject.po.UserPO;
import com.imooc.miaoshaproject.po.UserPasswordPO;
import com.imooc.miaoshaproject.service.UserService;
import com.imooc.miaoshaproject.service.model.UserModel;
import com.imooc.miaoshaproject.validator.ValidatorImpl;
import com.imooc.miaoshaproject.validator.ValidationResult;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import com.imooc.miaoshaproject.mapper.UserPasswordDOMapper;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDOMapper userDOMapper;

    @Autowired
    private UserPasswordDOMapper userPasswordDOMapper;

    @Autowired
    private ValidatorImpl validator;

    @Override
    public UserModel getUserById(Integer id) {
        UserPO userPO = userDOMapper.selectByPrimaryKey(id);
        if (userPO == null) {
            return null;
        }
        UserPasswordPO userPasswordPO = userPasswordDOMapper.selectByUserId(userPO.getId());
        return convertFromDataObject(userPO, userPasswordPO);
    }

    @Override
    @Transactional
    public void register(UserModel userModel) throws ServiceException {
        if (userModel == null) {
            throw new ServiceException(ErrorCodeEnum.PARAMETER_VALIDATION_ERROR);
        }
        ValidationResult result = validator.validate(userModel);
        if (result.isHasErrors()) {
            throw new ServiceException(ErrorCodeEnum.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
        }
        UserPO userPO = convertFromModel(userModel);
        try {
            userDOMapper.insertSelective(userPO);
        } catch (DuplicateKeyException ex) {
            throw new ServiceException(ErrorCodeEnum.PARAMETER_VALIDATION_ERROR, "手机号已重复注册");
        }
        userModel.setId(userPO.getId());
        UserPasswordPO userPasswordPO = convertPasswordFromModel(userModel);
        userPasswordDOMapper.insertSelective(userPasswordPO);
        return;
    }

    @Override
    public UserModel validateLogin(String telphone, String encrptPassword) throws ServiceException {
        //通过用户的手机获取用户信息
        UserPO userPO = userDOMapper.selectByTelphone(telphone);
        if (userPO == null) {
            throw new ServiceException(ErrorCodeEnum.USER_LOGIN_FAIL);
        }
        UserPasswordPO userPasswordPO = userPasswordDOMapper.selectByUserId(userPO.getId());
        UserModel userModel = convertFromDataObject(userPO, userPasswordPO);

        //比对用户信息内加密的密码是否和传输进来的密码相匹配
        if (!StringUtils.equals(encrptPassword, userModel.getEncrptPassword())) {
            throw new ServiceException(ErrorCodeEnum.USER_LOGIN_FAIL);
        }
        return userModel;
    }


    private UserPasswordPO convertPasswordFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserPasswordPO userPasswordPO = new UserPasswordPO();
        userPasswordPO.setEncrptPassword(userModel.getEncrptPassword());
        userPasswordPO.setUserId(userModel.getId());
        return userPasswordPO;
    }

    private UserPO convertFromModel(UserModel userModel) {
        if (userModel == null) {
            return null;
        }
        UserPO userPO = new UserPO();
        BeanUtils.copyProperties(userModel, userPO);

        return userPO;
    }

    private UserModel convertFromDataObject(UserPO userPO, UserPasswordPO userPasswordPO) {
        if (userPO == null) {
            return null;
        }
        UserModel userModel = new UserModel();
        BeanUtils.copyProperties(userPO, userModel);

        if (userPasswordPO != null) {
            userModel.setEncrptPassword(userPasswordPO.getEncrptPassword());
        }
        return userModel;
    }
}
